package controllers

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	common "jihe.common"
	"jihe.common/protos/order_server"
	order_server_proto "jihe.common/protos/order_server/proto"
	"jihe.common/protos/user_server"
	user_server_proto "jihe.common/protos/user_server/proto"
	"jihe.common/resp"
	"strconv"
	"strings"
	"time"
)

type OrderController struct {
	Redis common.Redis
}

func (s *OrderController) MakeProductionMaterial(c *gin.Context) {
	orderId := c.Query("order_id")
	if orderId == "" {
		resp.RespParamErr(c)
		return
	}
	ret, err := order_server.OrderGetDetailById(c, &order_server_proto.OrderOrder{Id: orderId})
	if err != nil {
		resp.RespGeneralErr(c, "不存在的订单")
		return
	}
	for _, v := range ret.BaseInfo.ProductionMaterials {
		vB, _ := json.Marshal(v)
		err = s.Redis.Get().LPush("production_material_consume", vB).Err()
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
	}
	resp.RespOk(c)
}

func (s *OrderController) GetOrderDetail(c *gin.Context) {
	id := c.Query("id")
	if id == "" {
		resp.RespParamErr(c)
		return
	}
	ret, err := order_server.OrderGetDetailById(c, &order_server_proto.OrderOrder{Id: id})
	if err != nil {
		if strings.Contains(err.Error(), "no rows") {
			resp.RespGeneralErr(c, "订单不存在")
			return
		}
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret)
}

func (s *OrderController) GetOrderList(c *gin.Context) {
	req := order_server_proto.OrderGetListReq{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize > 100 {
		req.PageSize = 100
	}
	duidsMap := make(map[string]int)
	cuidsMap := make(map[string]int)
	orderList, err := order_server.OrderGetList(c, &req)
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	if len(orderList.List) == 0 {
		resp.RespOk(c)
		return
	}
	for _, v := range orderList.List {
		cuidsMap[v.CUid] = 1
		duidsMap[v.DUid] = 1
		duidsMap[v.PayUid] = 1
	}
	duids := make([]string, 0)
	cuids := make([]string, 0)
	for uid, _ := range duidsMap {
		duids = append(duids, uid)
	}
	for uid, _ := range cuidsMap {
		cuids = append(cuids, uid)
	}
	dusers, err := user_server.UserDUserListByIds(c, &user_server_proto.UserDUserListByIdsReq{Uids: duids})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	cusers, err := user_server.UserGetCUsersByIds(c, &user_server_proto.UserGetCUsersByIdsReq{
		Uids: cuids,
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	retMap := make(map[string]interface{})
	retMap["base"] = orderList
	retMap["dusers"] = dusers.List
	retMap["cusers"] = cusers.List
	resp.RespOk(c, retMap)
}

func (s *OrderController) GetOrderStatusList(c *gin.Context) {
	ids := c.Query("ids")
	if ids == "" {
		resp.RespParamErr(c)
		return
	}
	idsArr := strings.Split(ids, ",")
	if len(idsArr) == 0 {
		resp.RespParamErr(c)
		return
	}
	ret, err := order_server.OrderGetStatusByIds(c, &order_server_proto.OrderGetStatusByIdsReq{
		OrderIds: idsArr,
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret.List)
}

func (s *OrderController) MoveProductionStatus(c *gin.Context) {
	orderId := c.Query("order_id")
	if orderId == "" {
		resp.RespParamErr(c)
		return
	}
	productionStatus := c.Query("production_status")
	productionStatusInt64, _ := strconv.ParseInt(productionStatus, 10, 64)
	if productionStatusInt64 == 0 {
		resp.RespParamErr(c)
		return
	}
	_, err := order_server.OrderProductionStatusMove(c, &order_server_proto.OrderOrder{
		Id:               orderId,
		ProductionStatus: productionStatusInt64,
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	if productionStatusInt64 == 4 {
		_, err = order_server.OrderLogisticsStatusMove(c, &order_server_proto.OrderOrder{
			Id:              orderId,
			LogisticsStatus: 1,
		})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
	}
	resp.RespOk(c)
}

func (s *OrderController) MoveLogisticsStatus(c *gin.Context) {
	orderId := c.Query("order_id")
	if orderId == "" {
		resp.RespParamErr(c)
		return
	}
	logisticsStatus := c.Query("logistics_status")
	logisticsStatusInt64, _ := strconv.ParseInt(logisticsStatus, 10, 64)
	if logisticsStatusInt64 == 0 {
		resp.RespParamErr(c)
		return
	}
	if logisticsStatusInt64 != 5 {
		_, err := order_server.OrderLogisticsStatusMove(c, &order_server_proto.OrderOrder{
			Id:              orderId,
			LogisticsStatus: logisticsStatusInt64,
		})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
	}
	if logisticsStatusInt64 == 5 { //确认收货，将提成给到设计师
		b, err := s.Redis.Get().SetNX(s.Redis.GetConfirmAmountKey(orderId), "1", time.Hour*2).Result()
		if err != nil || !b {
			resp.RespGeneralErr(c, "操作频繁")
			return
		}
		//获取订单信息
		orderDetail, err := order_server.OrderGetDetailById(c, &order_server_proto.OrderOrder{Id: orderId})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
		if orderDetail.LogisticsStatus == 5 {
			resp.RespGeneralErr(c, "已确认收货")
			return
		}
		_, err = order_server.OrderLogisticsStatusMove(c, &order_server_proto.OrderOrder{
			Id:              orderId,
			LogisticsStatus: logisticsStatusInt64,
		})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
		_, err = user_server.UserAddAmount(c, &user_server_proto.UserAccount{
			TotalAmount: orderDetail.RoyaltyPrice,
			Uid:         orderDetail.DUid,
		})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
	}
	resp.RespOk(c)
}

func (s *OrderController) GetWithDrawList(c *gin.Context) {
	req := order_server_proto.OrderGetWithdrawRecordListReq{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 || req.PageSize > 100 {
		req.PageSize = 20
	}
	withDrawList, err := order_server.OrderGetWithdrawRecordList(c, &req)
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	if len(withDrawList.List) == 0 {
		resp.RespOk(c)
		return
	}
	retMap := make(map[string]interface{})
	uidsMap := make(map[string]int)
	for _, v := range withDrawList.List {
		uidsMap[v.Uid] = 1
	}
	uids := make([]string, 0)
	for uid, _ := range uidsMap {
		uids = append(uids, uid)
	}
	userInfos, err := user_server.UserDUserListByIds(c, &user_server_proto.UserDUserListByIdsReq{Uids: uids})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	retMap["user_infos"] = userInfos.List
	retMap["base"] = withDrawList
	resp.RespOk(c, retMap)
}

func (s *OrderController) GetProductionMaterialList(c *gin.Context) {
	orderId := c.Query("order_id")
	if orderId == "" {
		resp.RespParamErr(c)
		return
	}
	ret, err := order_server.OrderGetProductionMaterialById(c, &order_server_proto.OrderGetProductionMaterialByIdReq{
		OrderId: orderId,
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret)
}

func (s *OrderController) MoveWithDrawStatus(c *gin.Context) {
	id := c.Query("id")
	if id == "" {
		resp.RespParamErr(c)
		return
	}
	idInt64, _ := strconv.ParseInt(id, 10, 64)
	if idInt64 == 0 {
		resp.RespParamErr(c)
		return
	}
	status := c.Query("status")
	statusInt64, _ := strconv.ParseInt(status, 10, 64)
	if statusInt64 == 0 {
		resp.RespParamErr(c)
		return
	}
	_, err := order_server.OrderWithdrawStatusMove(c, &order_server_proto.WithdrawRecord{
		Id:     idInt64,
		Status: statusInt64,
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c)
}
